package com.mach.platform.service;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mach.platform.domain.iot.IotDevParams;
import com.mach.platform.repository.IotDevParamsRepo;
import com.mach.platform.repository.IotDevRepo;
import com.mach.platform.utils.springdata.Collections3;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class AlarmServiceForeignImpl {

    @Autowired
    private AlarmServiceImpl alarmService;

    @Autowired
    private IotDevParamsRepo iotDevParamsRepo;

    @Autowired
    private IotDevRepo deviceRepo;

    @Autowired
    private CacheServiceImpl cacheService;

    /**
     * 复位的hashMap,存储所有报警设备属性的复位时间
     */
    public static Map resetMap = new HashMap();

    public static int isAlarm = 1;


    /**
     * 复位报警源，设置全部报警设备的属性一小时内不报警
     * @return
     */
    public boolean resetAlarmInfo() {
        // 1. 查询母排测温下面的所有设备id
        List<Integer> devIds = deviceRepo.findBusbarAllDevIds(AlarmServiceImpl.spaceId);
        // 2. 查询母排测温下面的所有设cur表的属性数据
        List<Map> mapListCur = deviceRepo.findAllByIotSpace(AlarmServiceImpl.spaceId, -1);
        // 3. 查询母排测温下面的所有设备win表的属性数据
        List<Map> mapListWin = AlarmServiceImpl.CUR_DATE_LIST;
        // 4. 找到所有母排测温所有设备的参数设定
        List<IotDevParams> iotDevParamsList = iotDevParamsRepo.findAllByDevIdIn(devIds);

        LocalDateTime nowTime = LocalDateTime.now();
        // 5. 找到所有报警的设备属性
        for (Integer devId : devIds) {
            List<Map> curMapList = new ArrayList<>();
            List<Map> winMapList = getWinDataByDevId(devId);
            List<IotDevParams> devParams = new ArrayList<>();
            // 找到每一个对应的设备属性cur表数据
            for (Map curMap : mapListCur) {
                if (curMap.get("id").equals(devId)) {
                    curMapList.add(curMap);
                }
            }

            // 找到每一个对应的设备属性win表数据
            /*for (Map winMap : mapListWin) {
                if (winMap.get("id").equals(devId)) {
                    winMapList.add(winMap);
                }
            }*/
            // 知道每一个设备对应的参数设定
            for (IotDevParams iotDevParams : iotDevParamsList) {
                if (iotDevParams.getDevId().equals(devId)) {
                    devParams.add(iotDevParams);
                }
            }
            // 开始判断设备数据是否报警
            Map alarmResult = getMap(curMapList, winMapList, devParams);
            // 6. 设置所有报警设备的属性一小时内不报警
            alarmResult.forEach((key, value) -> {
                if ((int) alarmResult.get(key) != 0) {
                    String devIdItem = devId + "_" + key;
                    resetMap.put(devIdItem, nowTime);
                }
            });
        }
        return true;
    }


    /**
     * 获取设备属性是否正常
     * @param devId 设备id
     * @return {key:A温度 value:{0：正常，非0：异常}}
     */
    public Map getItemStatusByDevId(Integer devId){
        List<Map> mapListCur = deviceRepo.findAllByIotSpace(AlarmServiceImpl.spaceId, devId);
        List<Map> mapListWin = getWinDataByDevId(devId);
        String devItem = devId + "params";
        List<IotDevParams> iotDevParams = (List<IotDevParams>) cacheService.getCache(devItem);
        if (null == iotDevParams) {
            iotDevParams = iotDevParamsRepo.findAllByDevId(devId);
            cacheService.putCache(devItem, iotDevParams);
        }
        Map result = getMap(mapListCur, mapListWin, iotDevParams);
        return result;
    }

    private Map getMap(List<Map> mapListCur, List<Map> mapListWin, List<IotDevParams> iotDevParams) {
        Map mapBound = alarmService.compareData(mapListCur, iotDevParams, false);
        Map mapTD = alarmService.compareTDByItem(mapListCur, iotDevParams, false);
        Map mapSuperline = alarmService.extractDataByMap(mapListWin, iotDevParams, false);
        return this.handleData(mapBound, mapTD, mapSuperline);
    }

    private List<Map> getWinDataByDevId(Integer devId){
        /*List<Map> curList = AlarmServiceImpl.CUR_DATE_LIST;
        List<Map> result = Lists.newArrayList();
        Iterator<Map> iterator = curList.iterator();
        while (iterator.hasNext()){
            Map map = iterator.next();
            Integer mapdevId = Integer.parseInt(map.get("id").toString());
            if (Objects.equals(mapdevId, devId)){
                result.add(map);
            }
        }*/
        ConcurrentHashMap<Integer, List<Map>> concurrentHashMap = AlarmServiceImpl.concurrentHashMap;
        List<Map> result = concurrentHashMap.get(devId);
        if (CollectionUtils.isEmpty(result)){
            return Collections.emptyList();
        }
        return result;
    }

    /**
     *
     * @param mapBound 上下限
     * @param mapTD 温差
     * @param mapSuperline 超线
     * @return
     */
    public Map handleData(Map mapBound, Map mapTD, Map mapSuperline) {
        Map result = Maps.newHashMap();
        result = setAlarmValue(mapBound, result);
        result = setAlarmValue(mapTD, result);
        result = setAlarmValue(mapSuperline, result);
        return result;
    }

    public Map setAlarmValue(Map source, Map result) {
        if (MapUtils.isEmpty(result)){
            return source;
        }
        int resultValue = 0;
        for (Object entry : source.entrySet()){
            Entry s = (Entry) entry;
            String key = s.getKey().toString();
            int value = Integer.parseInt(s.getValue().toString());
            if (resultValue != value){
                result.put(key, value);
            }
        }
        return result;
    }
}
